/**
 * http请求协议解析封装类, 轻量级, 主要用于编写API, 支持GET,POST,PUT,DELETE
 * 
 * 开发者   : Marco
 * 创建时间 : 2016年7月10日, 下午5:57
 */

#ifndef __MARCOPP_HTTP_REQUEST_H__
#define __MARCOPP_HTTP_REQUEST_H__

#include "basic.h"
#include <string>

MARCOPP_NAMESPACE_BEGIN
MARCOPP_NAMESPACE_HTTP_BEGIN

/** 请求方法类别
 */

class request_impl;

/**
 * 请求解析类
 */
class request : public basic {
public:
    request(version_type version = version_1_1, method_type method = method_get);
    request(const char* request_path, version_type version = version_1_1, method_type method = method_get);
    ~request(void);

    /**
     * 解析http数据, 数据必须包括整个http协议头, 允许只有部分正文, 解析发现与头中描述的Content-Length不符时, 返回http_parse_again
     * @param data 协议数据原始内容, 解析过程中会修改部分位置, 无论解析成功或失败, 此数据不得再使用.
     * @param data_len (in/out)数据长度, 返回未完成时(http_parse_again), 此变量返回还需多少字节.
     * @return 解析结果, 可能(完成,未完成,失败)
     */
    parse_result parse(char* data, int* data_len);
    
    /**
     * 获取与设置请求方法
     */
    method_type get_method(void) const;
    char* get_method_str(char* buf) const;
    void set_method(method_type method);
    
    /**
     * 获取与设置请求路径
     */
    char* get_urlpath(void);
    void set_urlpath(const char* urlpath); // 设置path
    void set_urlpath(const char* urlpath, int len); // 设置path,提供path长度
    
    /**
     * 添加url携带参数, 解析时会破坏原字符串
     * @param data 要解析的字符串, 格式: key=value&...
     * @return 是否处理成功
     */
    bool append_urlparam(char* data);
    
    /**
     * 根据url携带参数的名称获取值
     * @param name 名称
     * @return 值或NULL
     */
    char* get_urlparam(const char* name);
    
    /**
     * 获取url参数列表字符串形式, 格式: key1=value1&key2=value2&...
     * @param buf (out)存储缓冲区, 一个参数没有, 会是空串
     * @return 目标长度
     */
    int get_urlparam_str(char* buf);
    
    /**
     * 获取url参数个数
     * @return 个数
     */
    int get_urlparam_count(void) const;

private:
    request(const request& orig); // 禁用拷贝构造
    request& operator=(const request& orig); // 禁用拷贝赋值运算符重载

#if (__cplusplus >= 201103L)
    request(request&& orig) = delete; // 禁用移动构造
    request& operator=(request&& orig) = delete; // 禁用移动赋值运算符重载
#endif
    
    request_impl* impl;	// 实现类
};

MARCOPP_NAMESPACE_HTTP_END
MARCOPP_NAMESPACE_END
#endif /* __MARCOPP_HTTP_REQUEST_H__ */

